#ifndef __DRV_RC_H__
#define __DRV_RC_H__
#include "vpuapi.h"
#include "h265_interface.h"
#include "float_point.h"

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

#ifdef MAX
#undef MAX
#endif
#define MAX(a, b) (((a) > (b)) ? (a) : (b))

#ifdef MIN
#undef MIN
#endif
#define MIN(a, b) (((a) < (b)) ? (a) : (b))

#ifdef CLIP
#undef CLIP
#endif
#define CLIP(min, max, v) (MIN((MAX(min, v)), max))

#ifdef CLIP3
#undef CLIP3
#endif
#define CLIP3(min, max, x) ((x) < (min) ? (min) : ((x) > (max) ? (max) : (x)))

// float point constant abstraction
#if SOFT_FLOAT
// generated by script
#define  FLOAT_VAL_0 (0x0)
#define  FLOAT_VAL_10000 (0x461c4000)
#else
#define FLOAT_VAL_0 (0.)
#define FLOAT_VAL_10000 (10000.0)
#endif

#define AVBR_MAX_BITRATE_WIN 20
#define MOT_LV_DEFAULT 32
#define MOT_LOWER_THR 64

typedef enum { STEADY = 0, UNSTABLE = 1, RECOVERY = 2 } eRcState;

typedef enum {
    E_BITRATE = 0,
    E_FRAMERATE = 1,
} eRcParam;

typedef struct _stRQModel_ {
    int picPelNum;
    int lastQ;
    float alpha;
    float beta;
    float alphaStep;
    float betaStep;
} stRQModel;

typedef struct _stRcInfo_ {
    int frameIdx;
    int numOfPixel;
    int rcEnable;
    int targetBitrate;
    int picAvgBit;
    int maximumBitrate; // VBR, AVBR
    int bitrateBuffer;
    int frameSkipBufThr;
    int frameSkipCnt;
    int contiSkipNum;
    int skipPicture;

    int convergStateBufThr;
    int ConvergenceState;
    int codec;
    int rcMode; // 0:CBR, 1:VBR, 2:AVBR, 5:QpMap, 6:UBR
    int picIMinQp;
    int picIMaxQp;
    int picPMinQp;
    int picPMaxQp;
    int picMinMaxQpClipRange;
    int lastPicQp;
    eRcState rcState;
    int framerate;
    // AVBR
    int bitrateChangePeriod;
    int periodMotionLv;
    int lastPeriodMotionLv;
    int periodMotionLvRaw;
    int avbrContiSkipNum;
    int picMotionLvWindow[AVBR_MAX_BITRATE_WIN];
    int avbrLastPeriodBitrate;
    BOOL avbrChangeBrEn;
    BOOL isLastPicI;
    int avbrChangeValidCnt;
    int qDelta;

    // maxIprop
    int maxIPicBit;
    stRQModel IntraRqMdl;
    BOOL isReEncodeIdr;
    int s32SuperFrmBitsThr;
    BOOL bTestUbrEn;
    int s32HrdBufLevel;

    BOOL RcEn;
} stRcInfo;

#ifdef __cplusplus
}
#endif /* __cplusplus */

void venc_rc_open(stRcInfo *pRcInfo, EncOpenParam *pOpenParam);
void venc_rc_kernel_estimate_pic(stRcInfo *pRcInfo, EncParam *pEncParam, int frameIdx);
void venc_rc_update_frame_skip_setting(stRcInfo *pRcInfo, int frmLostOpen, int encFrmGaps, int frmLostBpsThr);
int venc_rc_chk_frame_skip_by_bitrate(stRcInfo *pRcInfo, int isIFrame);
BOOL venc_rc_state_check(stRcInfo *pRcInfo, BOOL detect);
BOOL venc_rc_avbr_pic_ctrl(stRcInfo *pRcInfo, EncOpenParam *pOpenParam, int frameIdx);
BOOL venc_rc_avbr_check_frame_skip(stRcInfo *pRcInfo, EncOpenParam *pOpenParam, int isIFrame);
int venc_rc_avbr_get_qpdelta(stRcInfo *pRcInfo, EncOpenParam *pOpenParam);
int venc_rc_get_param(stRcInfo *pRcInfo, eRcParam eParam);
int venc_rc_set_param(stRcInfo *pRcInfo, EncOpenParam *pOpenParam, eRcParam eParam);


#endif
